library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity fetch is
    port(
    Jump, PcSrcM, clk, rst:
        in std_logic;
    PcBranchM:
        in std_logic_vector(31 downto 0);
    InstrF, PCF, PCPlus4F:
        out std_logic_vector(31 downto 0)
    );
end fetch;

architecture behav of fetch is
    component mux2
        generic(n: integer);
        port(
        d0, d1: in std_logic_vector(n downto 0);
        s: in std_logic;
        y: out std_logic_vector(n downto 0)
        );
    end component;

    component flopr
        generic(n: integer);
        port(
        d : in std_logic_vector(n downto 0);
        clk, rst: in std_logic;
        q: out std_logic_vector(n downto 0)
        );
    end component;

    component imem
        port(
        a: in std_logic_vector(31 downto 0);
        rd: out std_logic_vector(31 downto 0)
        );
    end component;

    component adder
        port(
        a, b: in std_logic_vector(31 downto 0);
        s: out std_logic_vector(31 downto 0)
        );
    end component;

    signal PCPlus4F_s, PCBranchM_s, PCNext, PCF_s, InstrF_s, PCJump, PCp:
           std_logic_vector(31 downto 0);

begin
    IF_mux2_0: mux2
        generic map(31)
        port map(PCPlus4F_s, PCBranchM_s, PCSrcM, PCNext);

    IF_mux2_1: mux2
        generic map(31)
        port map(PCNext, PCJump, Jump, PCp);

    IF_flopr: flopr
        generic map(31)
        port map(PCp, clk, rst, PCF_s);

    IF_imem: imem
        port map(PCF_s, InstrF_s);

    IF_adder: adder
        port map(PCF_s, conv_std_logic_vector(4, 32), PCPlus4F_s);

    PCJump <= PCPlus4F_s(31 downto 28) & InstrF_s(25 downto 0) & "00";
    InstrF <= InstrF_s;
    PCF <= PCF_s;
    PCPlus4F <= PCPlus4F_s;
end behav;
